//
//  ChatView.swift
//  JiaoZiTaxi
//
//  Created by Hu Gang on 2022/10/12.
//

import AlertToast
import Combine
import PhotosUI
import SwiftUI

struct ChatView: View {
    @Environment(\.dismiss) var dismiss
   let chat: Chat
   
   @State var showRecordView = false

   var body: some View {
      GeometryReader { proxy in
         ZStack {
            VStack(spacing: 0) {
//               Separtor(color: Color("navigation_separator"))
                HStack {
                    Button(action: {
                        dismiss()
                    }, label: {
                        HStack {
                            Image(systemName: "chevron.backward")
                                .foregroundColor(.black)
                        }
                    })
                    Spacer()
                }.padding(.horizontal, 20).padding(.vertical, 20)
               MessageList()

               Send(proxy: proxy, showRecordView: self.$showRecordView)
                  .edgesIgnoringSafeArea(.bottom)
            }
            .background(Color("light_gray"))
            .navigationBarTitle(chat.senderName(), displayMode: .inline)
         }

         if showRecordView {
            VoiceRecordView().padding(.bottom, 80)
         }

      }.onAppear {
         ViewModel.shared.inChat = true
      }.onDisappear {
         ViewModel.shared.inChat = false
      }
   }

   enum EnumChatInputMode {
      case text
      case voice
   }

   struct Send: View {
      let proxy: GeometryProxy
      let openId = ViewModel.shared.passenger.openId
      let vm = ViewModel.shared
      @State private var text: String = ""
      @State private var phraseCode: String = "" // 短语
      @FocusState private var isTextFieldFocused: Bool
      @State private var showingImagePicker = false
      @State private var inputImage: UIImage?
      @State private var showingCameraPicker = false
      @State private var showPhraseSelect = false // 显示短语选择面板
      @State private var showToast = false
      @State private var toastMessage: String = ""
      @ObservedObject var keyboardHeightHelper = KeyboardHeightHelper()
      @StateObject  var vvm = VoiceViewModel()
      @Binding var showRecordView: Bool

      @State private var inputMode = EnumChatInputMode.text

      @State var isMicRightsGranted = false

      @GestureState private var isPressing = false
      @State var showFunctionsArea = true

      func sendVoice() {
         let newVoiceFilename = vvm.voiceFile!.replacingOccurrences(of: ".wav", with: ".mp3")
         print("[Voice] newVoiceFilename:\(newVoiceFilename)")
         AudioConverter.encodeToMp3(inPcmPath: vvm.voiceFile!, outMp3Path: newVoiceFilename) { p in
            print("[Voice] convert progress:\(p)")
         } onComplete: {
            print("[Voice] convert done.")

            do {
               try FileManager.default.removeItem(atPath: vvm.voiceFile!)
            } catch {
               print("[Voice] delete wav failure:\(error.localizedDescription)")
            }

            Api.uploadMp3(mp3Filename: newVoiceFilename) { r in
               switch r {
                  case .success(let data):
                     print("[Voice] upload result:\(data)")
                     do {
                        try FileManager.default.removeItem(atPath: newVoiceFilename)
                     } catch {
                        print("[Voice] delete mp3 failure:\(error.localizedDescription)")
                     }
                     DispatchQueue.main.sync {
                        let url = data.imgurl

                        let media = Media(cover: url, width: 0, height: 0, url: url)
                        let message = Message(createAt: Double(Date().secondsSince1970), image: media, sender: Member(identifier: openId, name: "我", openId: openId, type: .Passenger), text: text, type: .voice, voice: nil, video: nil, url: url, phraseCode: "")

                        CarOrder.shared.messages.append(message)
                        WebSocketService.shared.sendVoiceMessage(driverId: CarOrder.shared.driverId, orderId: CarOrder.shared.orderId, url: url)
                        CarOrder.shared.save()
                     }

                  case .failure(let err):
                     print("[Voice] login error:\(err.localizedDescription)")
               }
            }
         }
      }

      func checkMicroPermissionDothing() {
         AVAudioSession.sharedInstance().requestRecordPermission { granted in
            if granted {
               // The user granted access. Present recording interface.
               print("[Voice] recording rights granted.")
               self.isMicRightsGranted = true
            } else {
               // Present message to user indicating that recording
               // can't be performed until they change their preference
               // under Settings -> Privacy -> Microphone
               self.toastMessage = "未授予麦克风访问权！请前往 设置 —— 隐私 —— 麦克风 授权"
               self.showToast = true
            }
         }
      }

      func startRecord() {
         if isMicRightsGranted {
            print("[Voice] recording rights already granted.")

            vvm.startRecording()

         } else {
            toastMessage = "未授予麦克风访问权！请前往 设置 —— 隐私 —— 麦克风 授权"
            showRecordView = true
         }
      }

      var body: some View {
         VStack(spacing: 0) {
            Separtor(color: Color("chat_send_line"))

            HStack(spacing: 12) {
               if inputMode == .text {
                  Image(systemName: "wave.3.forward.circle")
                     .resizable()
                     .scaledToFit()
                     .frame(width: 28, height: 28)
                     .foregroundColor(.black)
                     .onTapGesture {
                        inputMode = .voice

                        checkMicroPermissionDothing()
                     }

                  TextField("请输入内容", text: $text)
                     .submitLabel(.send)
                     .frame(height: 40)
                     .padding(EdgeInsets(top: 0, leading: 6, bottom: 0, trailing: 6))
                     .background(Color("chat_send_text_background"))
                     .cornerRadius(4)
                     .onChange(of: text) { value in
                        print(value)
                     }
                     .onSubmit {
                        print("input:\(text)")
                        if text.count > 0 {
                           let message = Message(createAt: Double(Date().secondsSince1970), image: nil, sender: Member(identifier: openId, name: "我", openId: openId, type: .Passenger), text: text, type: .text, voice: nil, video: nil, url: nil,phraseCode:self.phraseCode)
                           print("message:\(message)")

                           CarOrder.shared.messages.append(message)
                           WebSocketService.shared.sendTextMessage(driverId: CarOrder.shared.driverId, orderId: CarOrder.shared.orderId, content: text,phraseCode: self.phraseCode)
                           
                           CarOrder.shared.save()
                           CarOrder.shared.messageCount += 1
                           text = ""
                           phraseCode = ""
                        }
                     }
               } else {
                  Image(systemName: "keyboard")
                     .resizable()
                     .scaledToFit()
                     .frame(width: 20, height: 20)
                     .foregroundColor(.black)
                     .padding(4)
                     .background(content: {
                        Circle()
                           .strokeBorder(.black, lineWidth: 2)
                     })
                     .onTapGesture {
                        inputMode = .text
                     }

                  RoundedRectangle(cornerRadius: 4, style: .continuous)
                     .fill(.white)
                     .overlay {
                        Text("按住 说话").foregroundColor(.black)
                     }

                     .frame(height: 40)
                     .frame(maxWidth: .infinity)
                     .gesture(
                        LongPressGesture(minimumDuration: 0.5)
                           .sequenced(before: DragGesture(minimumDistance: 0))
                           .updating($isPressing) { value, state, _ in
                              switch value {
                                 case .first(true):
                                    print("[Voice] 开始录音 \(vvm.isRecording)")
                                    state = true
                                    
                                    DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
                                       self.showRecordView = true
                                    }

                                    if !vvm.isRecording {
                                       print("[Voice] start to recording")
                                       startRecord()
                                    }

                                 default:
                                    break
                              }
                           }
                           .onEnded { value in
                              if case .second(true, _) = value {
                                 print("[Voice] 停止录音 \(vvm.isRecording)")
                                 // 添加停止录音的逻辑
                                 DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
                                    self.showRecordView = false
                                 }

                                    if vvm.isRecording {
                                       vvm.stopRecording()
                                       sendVoice()
                                    }
                              }
                           }
                     )
               }
//               Button {
//                  print("shift function menu")
//                  self.showFunctionsArea.toggle()
//               } label: {
//                  Image(systemName:"plus.circle")
//                     .resizable()
//                     .scaledToFit()
//                     .frame(width: 28, height: 28)
//                     .foregroundColor(.black)
//               }
            }
            .frame(height: 56)
            .padding(.horizontal, 12)


               // functions area
            if self.showFunctionsArea {
               HStack {
                   Spacer()
                  Button {
                     print("choose photo......")
                     self.showingImagePicker = true
                  } label: {

                      HStack {
                        Image(systemName: "photo.circle")
                           .resizable()
                           .scaledToFit()
                           .frame(width: 28, height: 28)
                           .foregroundColor(.black)

                        Text("相册")
                     }
                  }.padding()
                     .padding(.trailing,20)

                   Spacer()
                  Button {
                     self.showingCameraPicker.toggle()
                  } label: {
                      HStack {
                        Image(systemName: "camera.circle")
                           .resizable()
                           .scaledToFit()
                           .frame(width: 28, height: 28)
                           .foregroundColor(.black)

                        Text("拍照")
                     }
                  }.padding()
                     .padding(.trailing,20)
                   Spacer()

//                  Button {
//                     self.showPhraseSelect.toggle()
//                  } label: {
//                     VStack {
//                        Image(systemName: "list.bullet.circle")
//                           .resizable()
//                           .scaledToFit()
//                           .frame(width: 28, height: 28)
//                        Text("短语")
//                     }
//                  }.padding()


               } // end HStack of functions
               .foregroundColor(.black)
               .frame(width: UIScreen.main.bounds.width)
                  // .border(Color.gray, width: 1)
            } // end if of functions area
             
             List {
                ForEach(vm.getShortMessages(), id: \.self) { phrase in
                    Button {
                        print("phrase:\(phrase.content)")
                        self.text = phrase.content
                        self.phraseCode = phrase.code
                        self.showPhraseSelect = false
//                        self.isTextFieldFocused = true
                        let message = Message(createAt: Double(Date().secondsSince1970), image: nil, sender: Member(identifier: openId, name: "我", openId: openId, type: .Passenger), text: text, type: .text, voice: nil, video: nil, url: nil,phraseCode:self.phraseCode)
                        
                        CarOrder.shared.messages.append(message)
                        WebSocketService.shared.sendTextMessage(driverId: CarOrder.shared.driverId, orderId: CarOrder.shared.orderId, content: text,phraseCode: self.phraseCode)
                        CarOrder.shared.save()
                        CarOrder.shared.messageCount += 1
                        self.text = ""
                        self.phraseCode = ""
                    } label: {
                      Text(phrase.content)
                   }
                }
             }.frame(height: 300)
//                 .onAppear {
//                     self.showPhraseSelect.toggle()
//                 }
         }
         .background(Color(hex: "#dcdcdc"))
         .sheet(isPresented: self.$showingImagePicker) {
            ImagePicker(image: $inputImage)
         }
//         .sheet(isPresented: self.$showPhraseSelect, onDismiss: {
//            self.showPhraseSelect = false
//         }, content: {
//
//            VStack {
//
//               Text("发送短语")
//                  .font(.title3)
//                  .padding(.top,10)
//
//               List {
//                  ForEach(vm.getShortMessages(), id: \.self) { phrase in
//                      Button {
//                          print("phrase:\(phrase.content)")
//                          self.text = phrase.content
//                          self.phraseCode = phrase.code
//                          self.showPhraseSelect = false
////                        self.isTextFieldFocused = true
//                          let message = Message(createAt: Double(Date().secondsSince1970), image: nil, sender: Member(identifier: openId, name: "我", openId: openId, type: .Passenger), text: text, type: .text, voice: nil, video: nil, url: nil,phraseCode:self.phraseCode)
//                          
//                          CarOrder.shared.messages.append(message)
//                          WebSocketService.shared.sendTextMessage(driverId: CarOrder.shared.driverId, orderId: CarOrder.shared.orderId, content: text,phraseCode: self.phraseCode)
//                          CarOrder.shared.save()
//                          CarOrder.shared.messageCount += 1
//                          self.text = ""
//                          self.phraseCode = ""
//                      } label: {
//                        Text(phrase.content)
//                     }
//                  }
//               }
//
//               Button {
//                  self.showPhraseSelect = false
//               } label: {
//                  Image(systemName: "xmark.circle.fill")
//                     .font(.title2)
//                     .foregroundColor(.red)
//                     .padding()
//               }
//
//            }
//         })
         .toast(isPresenting: $showToast) {
            // `.alert` is the default displayMode
            AlertToast(type: .regular, title: self.toastMessage)
         }
         .sheet(isPresented: self.$showingCameraPicker, content: {
            CameraPicker(image: $inputImage)
         })
         .onChange(of: self.inputImage) { _ in
            guard let inputImage = inputImage else { return }

            self.hideKeyboard()

            let width = inputImage.size.width
            let height = inputImage.size.height

            let img = ImageInfo(image: inputImage, filename: "upload.jpg")

            Api.uploadImage(image: img) { r in
               switch r {
                  case .success(let data):
                     print("upload result:\(data)")
                     DispatchQueue.main.sync {
                        let url = data.imgurl

                        let media = Media(cover: url, width: width, height: height, url: url)
                        let message = Message(createAt: Double(Date().secondsSince1970), image: media, sender: Member(identifier: openId, name: "我", openId: openId, type: .Passenger), text: text, type: .image, voice: nil, video: nil, url: url, phraseCode: "")

                        CarOrder.shared.messages.append(message)
                        WebSocketService.shared.sendImageMessage(driverId: CarOrder.shared.driverId, orderId: CarOrder.shared.orderId, url: url)
                        CarOrder.shared.save()
                     }

                  case .failure(let err):
                     print("login error:\(err.localizedDescription)")
               }
            }
         }
      }
   }
}

struct ChatView_Previews: PreviewProvider {
   static var previews: some View {
      ChatView(chat: .hello)
   }
}
